package com.yuandian.management.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuandian.api.management.entity.ConfModuleManagement;
import com.yuandian.api.management.entity.ConfModuleManagementConfig;
import com.yuandian.bpm.admin.api.entity.SysDictItem;
import com.yuandian.bpm.admin.api.feign.RemoteDictService;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.constant.DictType;
import com.yuandian.constant.RedisKey;
import com.yuandian.enums.ModuleName;
import com.yuandian.management.enums.ModuleUpdateIdentityEnum;
import com.yuandian.management.mapper.ConfModuleManagementMapper;
import com.yuandian.management.service.ConfModuleManagementBaseConfigService;
import com.yuandian.management.service.ConfModuleManagementConfigService;
import com.yuandian.management.service.ConfModuleManagementService;
import com.yuandian.management.utils.RedisUtil;
import com.yuandian.management.vo.ModuleBaseConfigVo;
import com.yuandian.management.vo.ModulePrivateConfigVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 模块配置管理表-Service实现
 * @author zfsn
 * @date 2023-4-19
 */
@Service
@RequiredArgsConstructor
public class ConfModuleManagementServiceImpl extends ServiceImpl<ConfModuleManagementMapper, ConfModuleManagement>
		implements ConfModuleManagementService {

	private final ConfModuleManagementMapper confModuleManagementMapper;

	private final RemoteDictService remoteDictService;

	private final ConfModuleManagementConfigService moduleManagementConfigService;
	private final ConfModuleManagementBaseConfigService moduleManagementBaseConfigService;
	private final RedisUtil redisUtil;


	private final int ZERO_STATUS = 0;

	private final String MODULE_DACT_TYPE = "module_management";

	/**
	 * 心跳失活阀值
	 */
	private final String HART_INACTIVATION = "heart_inactivation";

	/**
	 * 更新超时阀值
	 */
	private final String UPDATE_TIMEOUT = "update_timeout";
	/**
	 * 查询模块管理列表信息
	 *
	 * @param confModuleManagement 参数
	 * @return
	 */
	@Override
	public R queryModuleManagementList(ConfModuleManagement confModuleManagement) {
		// 该类型只有两条记录，所以这里直接用类型取出来。
		List<SysDictItem> dataList = remoteDictService.getDictByType(DictType.MODULE_MANAGEMENT).getData();
		if (!CollectionUtils.isEmpty(dataList)) {
			for (SysDictItem dic : dataList) {
				if (dic.getLabel().equals(HART_INACTIVATION)) {
					// 更新运行状态
					Integer heartInactivation = Integer.parseInt(dic.getItemValue());
					confModuleManagementMapper.updateRunningStatus(heartInactivation);
				} else if (dic.getLabel().equals(UPDATE_TIMEOUT)) {
					// 更新配置状态
					Integer updateTimeout = Integer.parseInt(dic.getItemValue());
					confModuleManagementMapper.updateUpdateConfigFlagByCurrentTime(updateTimeout);
				}
			}
		}

		Page<ConfModuleManagement> list = confModuleManagementMapper.queryModuleManagementList(new Page<>(confModuleManagement.getPageNum(), confModuleManagement.getPageSize()), confModuleManagement);
		return R.ok(list);
	}

	/**
	 * 批量删除
	 *
	 * @param ids
	 * @return 结果
	 */
	@Override
	public R deleteModuleManagemenByIds(Integer[] ids) {
		int flag = confModuleManagementMapper.deleteModuleManagemenByIds(ids);
		if (flag > 0) {
			LambdaUpdateWrapper<ConfModuleManagementConfig> deleteWrapper = Wrappers.lambdaUpdate();
			deleteWrapper.in(ConfModuleManagementConfig::getModuleManagementId, ids);
			moduleManagementConfigService.remove(deleteWrapper);
		}

		return flag > 0 ? R.ok() : R.failed();
	}

	/**
	 * 根据id查询模块配置管理
	 *
	 * @param id 参数
	 * @return 通用结果
	 */
	@Override
	public R queryModuleManagementById(Integer id) {
		return R.ok(super.getById(id));
	}

	/**
	 * 新增或者修改模块配置管理
	 *
	 * @param module 参数
	 * @return 通用结果
	 */
	@Override
	public R insertOrUpdateModuleManagement(ConfModuleManagement module) {
		boolean flag = false;
		if (module.getId() != null) {
			// 修改的时候先查询同样模块
			ConfModuleManagement vo = new ConfModuleManagement();
			vo.setModuleName(module.getModuleName());
			vo.setModuleId(module.getModuleId());
			// 非探针的模块需要检查---修改的时候先查询同样模块，同一个groupid是否已经存在，因为同一个模块，groupId不能一样
			if (!ModuleName.BPM_PROBE.name().equals(module.getModuleName())) {
				List<ConfModuleManagement> list = confModuleManagementMapper.queryModuleManagementList(new Page<>(1, -1), vo).getRecords();
				if (!CollectionUtils.isEmpty(list) && list.get(0).getId().intValue() != module.getId().intValue()) {
					return R.failed("相同模块GROUPID不能相同！");
				}
			} else {
				// 探针模块检查同样的ip
				vo.setModuleIp(module.getModuleIp());
				List<ConfModuleManagement> list = confModuleManagementMapper.queryModuleManagementList(new Page<>(1, -1), vo).getRecords();
				if (!CollectionUtils.isEmpty(list) && list.get(0).getId().intValue() != module.getId().intValue()) {
					return R.failed("已存在相同配置信息！");
				}
			}

			module.setUpdateTime(LocalDateTime.now());
			flag = updateById(module);
		} else {
			ConfModuleManagement vo = new ConfModuleManagement();
			vo.setModuleName(module.getModuleName());
			vo.setModuleId(module.getModuleId());

			// 非探针的模块需要检查---新增的时候先查询同样模块，同一个groupid是否已经存在，因为同一个模块，groupId不能一样
			if (!ModuleName.BPM_PROBE.name().equals(module.getModuleName())) {
				List<ConfModuleManagement> list = confModuleManagementMapper.queryModuleManagementList(new Page<>(1, -1), vo).getRecords();
				if (!CollectionUtils.isEmpty(list)) {
					return R.failed("相同模块GROUPID不能相同！！");
				}
			} else {
				// 探针模块检查同样的ip
				vo.setModuleIp(module.getModuleIp());
				List<ConfModuleManagement> list = confModuleManagementMapper.queryModuleManagementList(new Page<>(1, -1), vo).getRecords();
				if (!CollectionUtils.isEmpty(list)) {
					return R.failed("已存在相同配置信息！");
				}
			}

			if (StrUtil.isBlank(module.getModulePort())) {
				module.setModulePort(" ");
			}

			module.setRunningStatus(ZERO_STATUS);
			module.setUpdateConfigFlag(ZERO_STATUS);
			flag = save(module);
			//如果复制来源ID不为空，需要复制模块详情配置
//			if(module.getCopyFromId()!=null && module.getCopyFromId().intValue()>0) {
//				ModulePrivateConfigVo mmc = new ModulePrivateConfigVo();
//				mmc.setModuleManagementId(module.getCopyFromId());
//				//存储公共配置和私有配置(如果配置名相同取私有的)
//				List<ModulePrivateConfigVo> mcList = modulePrivateConfigService.queryPrivateConfigListNoPage(mmc);
//				if(mcList!=null && mcList.size()>0) {
//				for(ModulePrivateConfigVo configVo : mcList) {
//						configVo.setModuleManagementId(module.getId());
//					}
//					modulePrivateConfigMapper.batchInsertModuleConfig(mcList);
//				}
//			}
		}
		return flag ? R.ok() : R.failed();
	}

	/**
	 * 读取存储公共配置和私有配置信息(如果配置名相同取私有的)
	 */
	@Override
	public void getConfigData() {
		ConfModuleManagement confModuleManagement = new ConfModuleManagement();
		confModuleManagement.setModuleName(ModuleName.BPM_WEB_MAIN.name());
		confModuleManagement.setPageSize(1);
		try {
			List<ConfModuleManagement> list = (List<ConfModuleManagement>) queryModuleManagementList(confModuleManagement).getData();
			if (!list.isEmpty()) {
				ConfModuleManagement moduleManagement = list.get(0);
				ModulePrivateConfigVo mmc = new ModulePrivateConfigVo();
				mmc.setModuleManagementId(moduleManagement.getId());
				//存储公共配置和私有配置(如果配置名相同取私有的)
				List<ModulePrivateConfigVo> mcList = moduleManagementConfigService.queryPrivateConfigListNoPage(mmc);
				ModuleBaseConfigVo mmb = new ModuleBaseConfigVo();
				mmb.setModuleCode(ModuleName.BPM_WEB_MAIN.name());
				List<ModuleBaseConfigVo> listBase = moduleManagementBaseConfigService.queryBaseConfigList(mmb);
				if (!listBase.isEmpty()) {
					for (ModuleBaseConfigVo configVo : listBase) {
						boolean flag = true;
						for (ModulePrivateConfigVo mbc : mcList) {
							if (configVo.getConfigName().equals(mbc.getConfigName())) {
								flag = false;
								break;
							}
						}
						if (flag) {
							ModulePrivateConfigVo mmcadd = new ModulePrivateConfigVo();
							mmcadd.setConfigName(configVo.getConfigName());
							mmcadd.setConfigDetails(configVo.getConfigDetails());
							mcList.add(mmcadd);
						}
					}
				}
				if (!mcList.isEmpty()) {
					for (ModulePrivateConfigVo mcv : mcList) {
						redisUtil.setCacheObject(RedisKey.SYS_MODULE_CONFIG +
								mcv.getConfigName(), mcv.getConfigDetails());
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 当更改了公有配置或者私有配置的时候更新模块状态：前提是有参数值更新才调用
	 * 系统触发更新配置为2: 待更新
	 * (配置更新标识 -1: 更新失败  0: 初始化  1:更新成功  2: 待更新  3: 更新中)
	 *
	 * @param id
	 * @return
	 */
	@Override
	public int updateConfigFlagById(Integer id) {
		return confModuleManagementMapper.updateConfigFlagById(id);
	}

	/**
	 * 当更改了公有配置或者私有配置的时候更新模块状态：前提是有参数值更新才调用
	 * 系统触发更新配置为2: 待更新
	 * (配置更新标识 -1: 更新失败  0: 初始化  1:更新成功  2: 待更新  3: 更新中)
	 *
	 * @param moduleCode
	 * @return
	 */
	@Override
	public int updateConfigFlagByModuleCode(String moduleCode) {
		return confModuleManagementMapper.updateConfigFlagByModuleCode(moduleCode);
	}

	/**
	 * 查询模块配置管理表 更新配置标记 -1:失败 0：初始化 1：成功 2：更新中
	 *
	 * @param moduleName 模块名称，探针''BPM_PROBE'',前台''BPM_WEB_MAIN'',实时流''BPM_RT_FLOW'',数据重组''BPM_DATA_SERVER'',后台配置''BPM_WEB_CONFIG''
	 * @return int
	 */
	@Override
	public int queryByUpdateConfigFlag(String moduleName) {
		return confModuleManagementMapper.queryByUpdateConfigFlag(moduleName);
	}

	/**
	 * 更新配置标记
	 *
	 * @param moduleName       模块名称
	 * @param moduleUpdateFlag 配置模块更新标识
	 * @return ModuleConfigVo
	 */
	@Override
	public int updateConfigFlagByModuleName(String moduleName, ModuleUpdateIdentityEnum moduleUpdateFlag) {
		ConfModuleManagement vo = new ConfModuleManagement();
		// 设置模块名称
		vo.setModuleName(moduleName);
		vo.setUpdateConfigFlag(moduleUpdateFlag.getCode());
		vo.setUpdateMessage(moduleUpdateFlag.getName());
		return confModuleManagementMapper.updateConfigFlagByModuleName(vo);
	}
}